using System;
using System.Collections.Generic;
using System.Net;
using System.Security.Cryptography;
using System.Text;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

namespace Mvvm.Services
{
    public class ImageGenerationService
    {
        // 定义API的凭证信息
        private const string appid = "8acbf43c"; // 填写控制台中获取的 APPID 信息
        private const string apiSecret = "MWM4M2QzY2NkMDFhNzc5ZDhiYTUyNzNj"; // 填写控制台中获取的 APISecret 信息
        private const string apiKey = "685a329f5eb2e0763c76922edbe08c0a"; // 填写控制台中获取的 APIKey 信息

        // 请求地址
        private const string createHostUrl = "https://cn-huadong-1.xf-yun.com/v1/private/s3fd61810/create";
        private const string queryHostUrl = "https://cn-huadong-1.xf-yun.com/v1/private/s3fd61810/query";

        public string GenerateImage(string prompt)
        {
            // 创建任务并获取任务ID
            string taskId = CreateTask(prompt);

            // 循环查询任务状态，直到任务完成
            int maxRetries = 50; // 设置最大重试次数
            int retries = 0; // 重试计数器

            while (true)
            {
                string res = QueryTask(taskId);
                try
                {
                    var response = JObject.Parse(res);
                    int code = (int)response["header"]["code"];
                    string task_status = (string)response["header"]["task_status"];

                    if (code == 0)
                    {
                        if (string.IsNullOrEmpty(task_status))
                        {
                            throw new Exception("查询任务状态有误，请检查");
                        }
                        else if (task_status == "3")
                        {
                            string fText = (string)response["payload"]["result"]["text"];
                            return "图片信息：\n" + Convert.FromBase64String(fText);
                        }
                        else
                        {
                            // 如果任务未完成，等待1秒后再次查询
                            System.Threading.Thread.Sleep(1000);
                            continue;
                        }
                    }
                    else
                    {
                        // 如果服务器返回非零状态码，抛出异常
                        throw new Exception($"Server returned error code: {code} - {response["header"]["message"]}");
                    }
                }
                catch (Exception ex)
                {
                    retries++;
                    Console.WriteLine($"Error occurred: {ex.Message}");
                    if (retries >= maxRetries)
                    {
                        throw; // 超过最大重试次数后，重新抛出异常
                    }
                    System.Threading.Thread.Sleep(1000); // 等待1秒后重试
                }
            }
        }

        private string CreateTask(string prompt)
        {
            // 构造请求数据
            var requestData = new
            {
                prompt = prompt,
                aspect_ratio = "1:1",
                negative_prompt = "",
                img_count = 1,
                resolution = "2k"
            };
            string jsonText = JsonConvert.SerializeObject(requestData);
            string bText = Convert.ToBase64String(Encoding.UTF8.GetBytes(jsonText));
            string requestUrl = CreateUrl(createHostUrl);
            var data = GenCreateRequestData(bText);
            var headers = GetHeaders(createHostUrl);
            var response = SendPost(requestUrl, JsonConvert.SerializeObject(data), headers);
            var resp = JObject.Parse(response);
            return (string)resp["header"]["task_id"];
        }

        private string QueryTask(string taskId)
        {
            var data = new
            {
                header = new
                {
                    app_id = appid,
                    task_id = taskId
                }
            };
            string requestUrl = CreateUrl(queryHostUrl);
            var headers = GetHeaders(queryHostUrl);
            var response = SendPost(requestUrl, JsonConvert.SerializeObject(data), headers);
            return response;
        }

        private string CreateUrl(string url)
        {
            Uri uri = new Uri(url);
            string host = uri.Host;
            string path = uri.PathAndQuery;

            // 生成RFC1123格式的时间戳
            string date = DateTime.UtcNow.ToString("R");

            // 拼接字符串
            string signatureOrigin = "host: " + host + "\n";
            signatureOrigin += "date: " + date + "\n";
            signatureOrigin += "POST " + path + " HTTP/1.1";

            // 进行hmac-sha256进行加密
            using (HMACSHA256 hmac = new HMACSHA256(Encoding.UTF8.GetBytes(apiSecret)))
            {
                byte[] signatureSha = hmac.ComputeHash(Encoding.UTF8.GetBytes(signatureOrigin));
                string signatureShaBase64 = Convert.ToBase64String(signatureSha);
                string authorizationOrigin = $"api_key=\"{apiKey}\", algorithm=\"hmac-sha256\", headers=\"host date request-line\", signature=\"{signatureShaBase64}\"";
                string authorization = Convert.ToBase64String(Encoding.UTF8.GetBytes(authorizationOrigin));

                // 将请求的鉴权参数组合为字典
                var v = new Dictionary<string, string>
                {
                    { "authorization", authorization },
                    { "date", date },
                    { "host", host }
                };

                // 拼接鉴权参数，生成url
                var queryParameters = new List<string>();
                foreach (var param in v)
                {
                    queryParameters.Add($"{param.Key}={WebUtility.UrlEncode(param.Value)}");
                }
                string reUrl = $"{url}?{string.Join("&", queryParameters)}";

                return reUrl;
            }
        }

        private Dictionary<string, string> GetHeaders(string url)
        {
            var headers = new Dictionary<string, string>
            {
                { "content-type", "application/json" },
                { "host", new Uri(url).Host },
                { "app_id", appid }
            };
            return headers;
        }

        private Dictionary<string, object> GenCreateRequestData(string bText)
        {
            return new Dictionary<string, object>
            {
                { "header", new Dictionary<string, object>
                    {
                        { "app_id", appid },
                        { "status", 3 },
                        { "channel", "default" },
                        { "callback_url", "default" }
                    }},
                { "parameter", new Dictionary<string, object>
                    {
                        { "oig", new Dictionary<string, object>
                            {
                                { "result", new Dictionary<string, object>
                                    {
                                        { "encoding", "utf8" },
                                        { "compress", "raw" },
                                        { "format", "json" }
                                    }
                                }
                            }
                        }
                    }},
                { "payload", new Dictionary<string, object>
                    {
                        { "oig", new Dictionary<string, object>
                            {
                                { "text", bText }
                            }
                        }
                    }
                }
            };
        }

        private string SendPost(string url, string data, Dictionary<string, string> headers)
        {
            using (WebClient client = new WebClient())
            {
                foreach (var header in headers)
                {
                    client.Headers.Add(header.Key, header.Value);
                }
                return client.UploadString(url, "POST", data);
            }
        }
    }
}